/*
* Copyright (c) 2003-2008 Rony Shapiro <ronys@users.sourceforge.net>.
* All rights reserved. Use of the code is allowed under the
* Artistic License 2.0 terms, as specified in the LICENSE file
* distributed with this code, or available from
* http://www.opensource.org/licenses/artistic-license-2.0.php
*/
// MyString.h
// A drop-in replacement for CString, the main difference being that the
// data is scrubbed by trashstring() in the destructor, thus leaving an attacker
// with a little less info to grovel for in the swap file / core dump / whatever
//
// First priority for porting is to implement this without CString
//-----------------------------------------------------------------------------

#ifndef _MYSTRING_H_
#define _MYSTRING_H_
#include <afx.h>
//-----------------------------------------------------------------------------
class CMyString
{
public:
  CMyString() : m_mystring(_T("")) {}
  CMyString(LPCTSTR lpsz) : m_mystring(lpsz) {}
  CMyString(LPCTSTR lpsz, int nLength) : m_mystring(lpsz, nLength) {}
  CMyString(const CMyString& stringSrc) : m_mystring(stringSrc.m_mystring) {}
  CMyString(const CString& stringSrc) : m_mystring(stringSrc) {}

  ~CMyString() {trashstring();}

  TCHAR operator[](int nIndex) const {return m_mystring[nIndex];}

  TCHAR GetAt(int nIndex) {return m_mystring.GetAt(nIndex);}

  void SetAt(int nIndex, TCHAR ch) {m_mystring.SetAt(nIndex,ch);}

  operator CString() const {return m_mystring;}
  operator CString&() {return m_mystring;}
  operator LPCTSTR() const {return (LPCTSTR)m_mystring;}

  BOOL IsEmpty() const {return m_mystring.IsEmpty();}

  const CMyString& operator=(const CMyString& stringSrc);
  const CMyString& operator=(TCHAR ch);
  const CMyString& operator=(LPCTSTR lpsz);
#ifndef UNICODE // do we need this at all?
  const CMyString& operator=(const unsigned char* psz);
#endif
  const CMyString& operator+=(const CMyString& s) {m_mystring += s.m_mystring; return *this;}
  const CMyString& operator+=(TCHAR ch) {m_mystring += ch; return *this;}
  const CMyString& operator+=(LPCTSTR lpsz) {m_mystring += lpsz; return *this;}

  // CMyString operator+(LPCTSTR lpsz);

  friend CMyString AFXAPI operator+(const CMyString& string1,
    const CMyString& string2);
  friend CMyString AFXAPI operator+(const CMyString& string,
    TCHAR ch);
  friend CMyString AFXAPI operator+(TCHAR ch,
    const CMyString& string);
  friend CMyString AFXAPI operator+(const CMyString& string,
    LPCTSTR lpsz);
  friend CMyString AFXAPI operator+(LPCTSTR lpsz,
    const CMyString& string);

  LPTSTR GetBuffer(int nMinBufLength) {return m_mystring.GetBuffer(nMinBufLength);}
  LPTSTR GetBuffer() {return m_mystring.GetBuffer();}

  void ReleaseBuffer(int nNewLength = -1) {m_mystring.ReleaseBuffer(nNewLength);}

  int GetLength() const {return m_mystring.GetLength();}

  int Find(TCHAR ch) const {return m_mystring.Find(ch);}
  int Find(LPCTSTR lpszSub) const {return m_mystring.Find(lpszSub);}
  int Find(TCHAR ch, int nstart) const {return m_mystring.Find(ch, nstart);}
  int Find(LPCTSTR lpszSub, int nstart) const {return m_mystring.Find(lpszSub, nstart);}
  int FindOneOf(LPCTSTR lpszSub) const {return m_mystring.FindOneOf(lpszSub);}
  int Replace(const TCHAR chOld, const TCHAR chNew) {return m_mystring.Replace(chOld,chNew);}
  int Replace(const LPCTSTR lpszOld, const LPCTSTR lpszNew)
  {return m_mystring.Replace(lpszOld,lpszNew);}
  int Remove(TCHAR ch) {return m_mystring.Remove(ch);}
  CMyString Left(int nCount) const;
  CMyString Right(int nCount) const;
  CMyString Mid(int nFirst) const;
  CMyString Mid(int nFirst, int nCount) const;
  void TrimRight() {m_mystring.TrimRight();}
  void TrimLeft() {m_mystring.TrimLeft();}
#if _MSC_VER >= 1400
  CMyString &Trim() {m_mystring.Trim(); return *this;}
#else
  CMyString &Trim()
  {m_mystring.TrimLeft(); m_mystring.TrimRight(); return *this}
#endif
  void MakeLower() {m_mystring.MakeLower();}
  int Compare(const LPCTSTR lpszOther) const {return m_mystring.Compare(lpszOther);}
  int CompareNoCase(const LPCTSTR lpszOther) const {return m_mystring.CompareNoCase(lpszOther);}
  void Empty();
  BOOL LoadString(const UINT &nID);
  void Format(LPCTSTR lpszFormat, ... );
  void Format(UINT nID, ... );
  BOOL IsOnlyWhiteSpace() const
  {CMyString t(*this); return t.Trim().IsEmpty();}
  void EmptyIfOnlyWhiteSpace()
  {if (IsOnlyWhiteSpace() == TRUE) Empty();}
  void Trash() {trashstring();}
  CMyString SpanIncluding(LPCTSTR lpszCharSet)
  {return CMyString(m_mystring.SpanIncluding(lpszCharSet));}
  CMyString SpanExcluding(LPCTSTR lpszCharSet)
  {return CMyString(m_mystring.SpanExcluding(lpszCharSet));}

private:
  CString m_mystring;
  void trashstring();
};
//-----------------------------------------------------------------------------

inline bool operator==(const CMyString& s1, const CMyString& s2)
{return (const CString)s1 == (const CString)s2;}
inline bool operator==(const CMyString& s1, LPCTSTR s2)
{return (const CString)s1==s2;}
inline bool operator==(LPCTSTR s1, const CMyString& s2)
{return s1==(const CString)s2;}
inline bool operator!=(const CMyString& s1, const CMyString& s2)
{return (const CString)s1 != (const CString)s2;}
inline bool operator!=(const CMyString& s1, LPCTSTR s2)
{return (const CString)s1 != s2;}
inline bool operator!=(LPCTSTR s1, const CMyString& s2)
{return s1 != (const CString)s2;}

//-----------------------------------------------------------------------------
#endif
//-----------------------------------------------------------------------------
// Local variables:
// mode: c++
// End:

